#ifndef __NODE_2D_H__
#define __NODE_2D_H__

#include <iostream>
#include <vector>
#include <memory> 
#include <cmath>
using namespace std;

class Node2D;
using Node2DPtr = std::shared_ptr<Node2D>;

class Node2D{
    
    public:
        Node2D(): Node2D(0, 0, 0, 0){};
        Node2D(int x, int y, float g, float h) {
            this->x = x;
            this->y = y;
            this->g = g;
            this->h = h;
            this->pred = nullptr;
            this->idx = -1;
        }  

        int getX() const { return x; }
        int getY() const { return y; }
        int getIdx() const { return idx; }
        float getG() const { return g; }
        float getH() const { return h; }
        float getF() const { return g + h; }
        Node2DPtr getPred() const { return pred; }

        void setX(int x) { this->x = x; }
        void setY(int y) { this->y = y; }
        int setIdx(int width) { 
            this->idx = this->y * width + this->x; 
            return idx; 
        }
        void setG(float g) { this->g = g; }
        void setH(float h) { this->h = h; }
        void setPred(Node2DPtr pred) { this->pred = pred; }


        // 启发函数
        float movementCost(const Node2D& pred) const;
        void updateG() { 
            this->g += movementCost(*pred); 
        }
        void updateH(const Node2D& goal) { 
            this->h = movementCost(goal); 
        }

        // 比较节点是否相同
        bool operator == (const Node2D& rhs) const;


        // 邻域
        static const int dir;
        static const int dx[];
        static const int dy[];


    private:
        int x, y, idx;
        float g, h, f;
        Node2DPtr pred;

};

#endif